package com.xzj.admin.analysis.base.custom.it;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xzj.admin.analysis.base.common.handle.CommonAbstractAnalysisHandle;
import com.xzj.admin.analysis.base.constants.CommonEnums;
import com.xzj.admin.analysis.base.custom.common.CommonAnalysis;
import com.xzj.admin.analysis.base.util.AnalysisCommonUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: xzj-admin
 * @ClassName: VcAnalysisHandle
 * @description: IT云VC
 * @author: XiaZunJun
 * @create: 2024-11-12 08:49
 */
public class VcAnalysisHandle extends CommonAbstractAnalysisHandle {

    public VcAnalysisHandle(String cloudId,String cloudType) {
        super(cloudId, cloudType,new VcThemeSpecialAnalysisHandle(cloudId,cloudType));
    }

    private static final List<String> VM_DEVICE_ANALYSIS_LIST = new ArrayList<>();

    static {
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.region.name(), CommonAnalysis::regionSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.host.name(), VcAnalysisHandle::hostSub);
        registerJudgeSubFun("parentMOR:val", VcAnalysisHandle::hostRelateClusterSub);
        registerJudgeSubFun("datastores", VcAnalysisHandle::hostDataStoreSub);
        registerJudgeSubFun("config:fileSystemVolume:mountInfo", VcAnalysisHandle::hostVolumeSub);
        registerJudgeSubFun("config:network:vnic", VcAnalysisHandle::hostVNicSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.vm.name(), VcAnalysisHandle::vmSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.network.name(), VcAnalysisHandle::networkSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.vSwitch.name(), VcAnalysisHandle::vSwitchSub);
        registerJudgeSubFun(CommonEnums.RESOURCE_TYPE.portGroup.name(), VcAnalysisHandle::portGroupSub);
        // 硬盘
        VM_DEVICE_ANALYSIS_LIST.add("VirtualDisk");
        // 控制器
        VM_DEVICE_ANALYSIS_LIST.add("Controller");
        // 网络适配器
        VM_DEVICE_ANALYSIS_LIST.add("VirtualVmxnet3");
        // 显卡
        VM_DEVICE_ANALYSIS_LIST.add("VirtualMachineVideoCard");
        // VMCI
        VM_DEVICE_ANALYSIS_LIST.add("VirtualMachineVMCIDevice");
        // Keyboard
        VM_DEVICE_ANALYSIS_LIST.add("VirtualKeyboard");
        // 探针
        VM_DEVICE_ANALYSIS_LIST.add("PointingDevice");
        // CD/DVD驱动器
        VM_DEVICE_ANALYSIS_LIST.add("VirtualCdrom");
    }

    /**
     * 构建依托于主机 主机与虚拟存储关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void hostSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        if (isJudgeSubFun(fieldName)) {
            getJudgeSubFun(fieldName).accept(row, parentId, fieldName, subThemeRows);
        }
    }

    /**
     * 构建依托于主机 主机网卡信息
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void hostVNicSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        // config:network:vnic
        JSONObject config = row.getJSONObject("config");
        if (null != config) {
            JSONObject network = config.getJSONObject("network");
            if (null != network) {
                JSONArray vnics = network.getJSONArray("vnic");
                if (null != vnics) {
                    for (int i = 0; i < vnics.size(); i++) {
                        JSONObject vnic = vnics.getJSONObject(i);
                        vnic.put("deviceId", parentId);
                        String key = vnic.getString("key");
                        if (StrUtil.isNotEmpty(key)) {
                            vnic.put("id", AnalysisCommonUtil.commonBuildStr(parentId, key));
                            subThemeRows.add(vnic);
                        }
                    }
                }
            }
        }
    }

    /**
     * 构建依托于主机 主机磁盘信息
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void hostVolumeSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        // config:fileSystemVolume:mountInfo
        JSONObject config = row.getJSONObject("config");
        if (null != config) {
            JSONObject fileSystemVolume = config.getJSONObject("fileSystemVolume");
            if (null != fileSystemVolume) {
                JSONArray mountInfos = fileSystemVolume.getJSONArray("mountInfo");
                if (null != mountInfos) {
                    for (int i = 0; i < mountInfos.size(); i++) {
                        JSONObject mountInfo = mountInfos.getJSONObject(i);
                        mountInfo.put("deviceId", parentId);
                        String volumeId = mountInfo.getJSONObject("volume").getString("uuid");
                        if (StrUtil.isNotEmpty(volumeId)) {
                            mountInfo.put("id", AnalysisCommonUtil.commonBuildStr(parentId, volumeId));
                            subThemeRows.add(mountInfo);
                        }
                    }
                }
            }
        }
    }

    /**
     * 构建依托于主机 主机与虚拟存储关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void hostDataStoreSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        JSONArray datastores = row.getJSONArray(fieldName);
        for (int i = 0; i < datastores.size(); i++) {
            String datastoreId = datastores.getJSONObject(i).getString("val");
            JSONObject subJson = new JSONObject();
            subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, datastoreId));
            subJson.put("deviceId", parentId);
            subJson.put("storagePoolId", datastoreId);
            subJson.put("specId", "12580002");
            subThemeRows.add(subJson);
        }
    }

    /**
     * 构建依托于主机 主机与集群关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void hostRelateClusterSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        String[] subs = fieldName.split(CommonEnums.JOIN.DEFAULT.getValue());
        String clusterId = row.getJSONObject(subs[0]).getString(subs[1]);
        JSONObject subJson = new JSONObject();
        subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, clusterId));
        subJson.put("deviceId", parentId);
        subJson.put("clusterId", clusterId);
        subThemeRows.add(subJson);
    }

    /**
     * 构建依托于网络 网络与主机虚机关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void networkSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        JSONArray subJsons = row.getJSONArray(fieldName);
        if (fieldName.equals("hosts")) {
            // 网络与主机
            commonSub(subJsons, parentId, "12960001", subThemeRows);
        } else {
            // 网络与虚机
            commonSub(subJsons, parentId, "12960002", subThemeRows);
        }
    }

    /**
     * 构建依托于虚拟交换机 虚拟交换机与主机虚机关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void vSwitchSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        String[] subs = fieldName.split(CommonEnums.JOIN.DEFAULT.getValue());
        if (subs.length == 2) {
            JSONArray subJsons = row.getJSONObject(subs[0]).getJSONArray(subs[1]);
            if (subs[1].equals("hostMember")) {
                // 虚拟交换机与主机
                commonSub(subJsons, parentId, "12960001", subThemeRows);
            } else {
                // 虚拟交换机与虚机
                commonSub(subJsons, parentId, "12960002", subThemeRows);
            }
        }
    }

    /**
     * 构建依托于端口组 端口组与主机虚机关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void portGroupSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        JSONArray subJsons = row.getJSONArray(fieldName);
        if (fieldName.equals("hosts")) {
            // 端口组与主机
            commonSub(subJsons, parentId, "13090001", subThemeRows);
        } else {
            // 端口组与虚机
            commonSub(subJsons, parentId, "13090002", subThemeRows);
        }
    }

    private static void commonSub(JSONArray subJsons, String parentId, String value, JSONArray subThemeRows) {
        if (null != subJsons && subJsons.size() > 0) {
            for (int i = 0; i < subJsons.size(); i++) {
                JSONObject subJson = subJsons.getJSONObject(i);
                subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, subJson.getString("val")));
                subJson.put("parentId", parentId);
                subJson.put("specId", value);
                subThemeRows.add(subJson);
            }
        }
    }

    /**
     * 构建依托于虚机 虚机与虚拟存储关系
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    public static void vmSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        if ("datastores".equals(fieldName)) {
            JSONArray vmDatastoreS = row.getJSONArray(fieldName);
            for (int i = 0; i < vmDatastoreS.size(); i++) {
                String datastoreId = vmDatastoreS.getJSONObject(i).getString("val");
                JSONObject subJson = new JSONObject();
                subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, datastoreId));
                subJson.put("vmId", parentId);
                subJson.put("storagePoolId", datastoreId);
                subJson.put("specId", "12580003");
                subThemeRows.add(subJson);
            }
        } else {
            vmDeviceSub(row, parentId, fieldName, subThemeRows);
        }
    }

    /**
     * 构建依托于虚机 虚机硬件扩展信息
     *
     * @param row          父级节点解析对象体
     * @param parentId     对应父级节点Id
     * @param fieldName    对应子集字段名
     * @param subThemeRows 子数据源解析对象
     * @author xiazunjun
     * @date 2023/11/13 14:50
     */
    private static void vmDeviceSub(JSONObject row, String parentId, String fieldName, JSONArray subThemeRows) {
        // config:hardware:device
        String[] fields = fieldName.split(CommonEnums.JOIN.DEFAULT.getValue());
        JSONObject config = row.getJSONObject(fields[0]);
        if (null != config) {
            JSONObject hardware = config.getJSONObject(fields[1]);
            if (null != hardware) {
                JSONArray devices = hardware.getJSONArray(fields[2]);
                for (int i = 0; i < devices.size(); i++) {
                    JSONObject subJson = devices.getJSONObject(i);
                    String type = subJson.getString("@type");
                    if (null != type) {
                        for (String analysisType : VM_DEVICE_ANALYSIS_LIST) {
                            if (type.endsWith(analysisType)) {
                                String[] typeSplit = type.split("\\.");
                                subJson.put("@type", typeSplit[typeSplit.length - 1]);
                                subJson.put("vmId", parentId);
                                String label =
                                        subJson.getJSONObject("deviceInfo").getString("label").replaceAll("\\s*", "");
                                subJson.put("id", AnalysisCommonUtil.commonBuildStr(parentId, label));
                                subThemeRows.add(subJson);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}
